#if !defined(ximera_gui_iwindow_hpp)
#define ximera_gui_iwindow_hpp

// -----------------------------------------------------------

#include <ximera/types.hpp>
#include <ximera/math/vector2.hpp>
#include <ximera/common/signal.hpp>
#include <ximera/common/eventargs.hpp>
#include <ximera/input/codes.hpp>

namespace ximera { namespace gui
{
    class IWindow;

    struct GuiEventArgs : EventArgs
    {
        GuiEventArgs(IWindow* sender)
            : sender(sender) {}

        IWindow* sender;
    };

    struct MouseEventArgs : GuiEventArgs
    {
        MouseEventArgs(IWindow* sender)
            : GuiEventArgs(sender) {}

        math::Vector2 position;
        math::Vector2 delta;
        input::MouseCode button;
        UInt32 clicks;
    };

    struct KeyEventArgs : GuiEventArgs
    {
        KeyEventArgs(IWindow* sender)
            : GuiEventArgs(sender) {}

        input::KeyCode keyCode;
    };

    struct KeyCharEventArgs : GuiEventArgs
    {
        KeyCharEventArgs(IWindow* sender)
            : GuiEventArgs(sender) {}

        Char key;
    };

    typedef void (ClickEvent)(GuiEventArgs& e);
    typedef void (MouseEnterEvent)(GuiEventArgs& e);
    typedef void (MouseExitEvent)(GuiEventArgs& e);
    typedef void (MouseMoveEvent)(MouseEventArgs& e);
    typedef void (MouseDownEvent)(MouseEventArgs& e);
    typedef void (MouseUpEvent)(MouseEventArgs& e);
    typedef void (KeyDownEvent)(KeyEventArgs& e);
    typedef void (KeyUpEvent)(KeyEventArgs& e);

    class XIMERA_API IWindow
    {
    public:
        virtual ~IWindow();

        virtual Real left() const = 0;
        virtual void left(Real value) = 0;

        virtual Real top() const = 0;
        virtual void top(Real value) = 0;

        virtual Real width() const = 0;
        virtual void width(Real value) = 0;

        virtual Real height() const = 0;
        virtual void height(Real value) = 0;

        virtual math::Vector2 position() const = 0;
        virtual void position(math::Vector2 const& value) = 0;
        virtual void position(Real left, Real top) = 0;

        virtual math::Vector2 size() const = 0;
        virtual void size(math::Vector2 const& value) = 0;
        virtual void size(Real width, Real height) = 0;

        virtual String text() const = 0;
        virtual void text(String const& value) = 0;

        virtual bool visible() const = 0;
        virtual void visible(bool value) = 0;

        virtual bool enabled() const = 0;
        virtual void enabled(bool value) = 0;

        virtual IWindow* parent() const = 0;

        virtual UInt32 childCount() const = 0;
        virtual IWindow* child(UInt32 index) const = 0;

        virtual void addChild(IWindow* child) = 0;
        virtual void removeChild(IWindow* child) = 0;
        virtual void removeAllChildren() = 0;

        virtual bool isChild(IWindow* child) = 0;

        virtual void show() = 0;
        virtual void hide() = 0;

        virtual void bringToFront() = 0;
        virtual void sendToBack() = 0;

        virtual void beginUpdate() = 0;
        virtual void endUpdate() = 0;

        virtual SignalAccess<ClickEvent> onClick() = 0;
        virtual SignalAccess<MouseEnterEvent> onMouseEnter() = 0;
        virtual SignalAccess<MouseExitEvent> onMouseExit() = 0;
        virtual SignalAccess<MouseMoveEvent> onMouseMove() = 0;
        virtual SignalAccess<MouseDownEvent> onMouseDown() = 0;
        virtual SignalAccess<MouseUpEvent> onMouseUp() = 0;
        virtual SignalAccess<KeyDownEvent> onKeyDown() = 0;
        virtual SignalAccess<KeyUpEvent> onKeyUp() = 0;
    };
}}

// -----------------------------------------------------------

#endif
